<div id="app">{{title}}</div>

<script>
  // 填充代码
  // 1. 基本结构
  const Vue = {
    // 拓展性
    createRenderer({
      querySelector,
      insert
    }) {
      // 返回渲染器
      return {
        createApp(options) {
          // 返回app对象
          return {
            mount(selector) {
              // 1. 找到宿主元素
              const parent = querySelector(selector)
              // 2. 渲染页面
              if (!options.render) {
                // 2.1 处理template： 编译
                options.render = this.compile(parent.innerHTML)
              }

              // 收集 setup 和其他选项
              if (options.setup) {
                this.setupState = options.setup()
              }
              if (options.data) {
                this.data = options.data()
              }

              // 渲染之前，处理setup和其他选项的兼容
              const proxy = new Proxy(this, {
                get(target, key) {
                  // 先从setup中取，如果取不到再从data中取
                  // 如果setup存在，且key在setup中定义过
                  if (target.setupState && key in target.setupState) {
                    // return target.setupState[key]
                    return Reflect.get(target.setupState, key)
                  } else {
                    // return target.data[key]
                    return Reflect.get(target.data, key)
                  }

                },
                set(target, key, val) {
                  if (target.setupState && key in target.setupState) {
                    return Reflect.set(target.setupState, key, val)
                  } else {
                    return Reflect.set(target.data, key, val)
                  }
                }
              })


              // 2.2 用户直接编写render
              // 执行render函数（这里指定render函数中的this的上下文，是配置项中data函数的返回值）
              const el = options.render.call(proxy)

              // 3. 追加到宿主
              insert(el, parent)
            },
            compile(template) {
              // 返回一个render函数
              // parse -> ast
              // generate: ast -> render
              return function render() {
                const h3 = document.createElement('h3')
                h3.textContent = this.title
                return h3
              }
            }
          }
        }
      }
    },
    createApp(options) {
      // 创建一个web平台特有的渲染器
      const renderer = Vue.createRenderer({
        querySelector(sel) {
          return document.querySelector(sel)
        },
        insert(el, parent) {
          parent.innerHTML = ''
          parent.appendChild(el)
        }
      })
      return renderer.createApp(options)
    }

  }
</script>

<script>
  const app = Vue.createApp({
    data() {
      return {
        title: 'hello, vue3 YK菌 data'
      }
    },
    setup() {
      return {
        title: 'hello, vue3 YK菌 setup'
      }
    }
  })
  app.mount('#app')
</script>